<template>
  <div class="container">
    <div class="app-container">
      <div class="btnrole">
        <el-button type="primary" size="mini" @click="adddailog = true">添加角色</el-button>
      </div>
      <!-- 表格 -->
      <el-table :data="rolelist" stripe style="width: 100%">
        <el-table-column prop="name" label="角色" align="center" width="200px">
          <template v-slot="{ row }">
            <el-input v-if="row.isedit" v-model="row.rowedit.name"></el-input>
            <span v-else>{{ row.name }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="state" label="启用" align="center" width="200">
          <!-- 作用域插槽 -->
          <template v-slot="{ row }">
            <el-switch v-if="row.isedit" v-model="row.rowedit.state" active-color="#13ce66" inactive-color="#ccc"
              :active-value="1" :inactive-value="0">
            </el-switch>
            <span v-else> {{ row.state === 1 ? '已启用' : '未启用' }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="详细" align="center">
          <template v-slot="{ row }">
            <el-input v-if="row.isedit" v-model="row.rowedit.description" type="textarea"></el-input>
            <span v-else>{{ row.description }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center">
          <template v-slot="{ row }">
            <template v-if="row.isedit">
              <el-button type="primary" size="mini" @click="editok(row)">确定</el-button>
              <el-button type="success" size="mini" @click="row.isedit = false">取消</el-button>
            </template>
            <template v-else>
              <el-button type="text" @click="setrolebtn(row.id)">分配权限</el-button>
              <el-button type="text" @click="btnedit(row)">编辑</el-button>
              <el-popconfirm title="这是一段内容确定删除吗？" @onConfirm="delrole(row.id)">
                <el-button style="margin-left: 5px;" slot="reference" type="text">删除</el-button>
              </el-popconfirm>
            </template>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页-->
      <el-row type="flex" justify="end" style="height: 50px;" align="middle">
        <el-pagination small layout="prev, pager, next,sizes" :total="total" :page-size="queryinfo.pagesize"
          @size-change="changesie" :page-sizes="[3, 4, 5, 6]" @current-change="changecurr">
        </el-pagination>
      </el-row>
    </div>
    <!-- 添加角色的对话框 -->
    <el-dialog title="新增角色" :visible.sync="adddailog" width="30%" @close="close">
      <el-form :model="addroleinfo" :rules="addrolerule" ref="roleref" label-width="100px">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="addroleinfo.name"></el-input>
        </el-form-item>
        <el-form-item label="启用" prop="state">
          <el-switch v-model="addroleinfo.state" active-color="#13ce66" inactive-color="#ccc" :active-value="1"
            :inactive-value="0">
          </el-switch>
        </el-form-item>
        <el-form-item label="角色描述" prop="description">
          <el-input v-model="addroleinfo.description" type="textarea"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="close">取 消</el-button>
        <el-button type="primary" @click="isok">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 分配角色对话框 -->
    <el-dialog title="分配权限" :visible.sync="setroleshow" width="30%" @close="perclose">
      <el-tree :data="perlist" show-checkbox node-key="id" default-expand-all :props="defaultProps"
        :default-checked-keys="byidroledata" ref="treeper">
      </el-tree>
      <span slot="footer" class="dialog-footer">
        <el-button @click="perclose">取 消</el-button>
        <el-button type="primary" @click="queryperbtn">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import { getrolelist, addrole, updatarole, delrole, getbyidrole, putper } from '@/api/role';
import { getperdata } from '@/api/permission';
import { listchangetree } from '@/utils';
export default {
  name: 'Role',
  data() {
    return {
      //角色列表
      rolelist: [],
      //查询参数
      queryinfo: {
        page: 1,//页数
        pagesize: 3//每页显示的条数
      },
      //总数
      total: 0,
      //对话框显示
      adddailog: false,
      //新增角色信息
      addroleinfo: {
        name: '',
        state: 0,
        description: ''
      },
      addrolerule: {
        name: [{ required: true, message: '角色名称不能为空', trigger: 'blur' },],
        description: [{ required: true, message: '详情不能为空', trigger: 'blur' }]
      },
      //分配权限对话框是否显示
      setroleshow: false,
      //原始的权限数据
      firstperlist: [],
      //树形组件绑定的数据
      perlist: [],
      //树形组件的配置对象
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      //当前选中的id
      activeid: null,
      //根据id获取的详细角色信息里的权限数组集合
      byidroledata: []
    }
  },
  methods: {
    //获取角色信息
    async getroledata() {
      //获取权限列表
      //这里只需要获取一次权限列表,但树形组件绑定的数据需要重新赋值
      //要不然每次树形组件中选定的checkbox都是上次点击的节点的选中的值
      this.firstperlist = listchangetree(await getperdata(), 0)
      const res = await getrolelist(this.queryinfo)
      this.rolelist = res.rows
      //进行行内编辑 给列表中的一个对象都添加一个记录是否编辑的状态
      this.rolelist.forEach(Item => {
        //这个属性保存是否编辑
        //注意这里会有数据响应式问题
        //当给一个响应式数据动态添加一个属性时,这个属性是不具备响应式的
        //this.$set(对象,属性.默认值)
        this.$set(Item, 'isedit', false)
        //添加一个对象 里面保存编辑时的数据
        //给这个对象添加默认值,值是当前编辑行的原始数据
        this.$set(Item, 'rowedit', { name: Item.name, description: Item.description, state: Item.state })
      })
      this.total = res.total
    },
    //size改变时发起请求
    changesie(val) {
      this.queryinfo.pagesize = val
      this.getroledata(this.queryinfo)
    },
    //页数改变时发送请求
    changecurr(val) {
      this.queryinfo.page = val
      this.getroledata()
    },
    //添加角色关闭对话框
    close() {
      this.adddailog = false
      //resetFields只能重置模板中绑定的数据
      //只有绑定prop属性的才能重置表单数据
      this.$refs.roleref.resetFields()
    },
    //添加角色对话框确认
    isok() {
      this.$refs.roleref.validate(async is => {
        if (is) {
          await addrole(this.addroleinfo)
          this.$message.success('添加角色成功')
          this.getroledata()
        }
        this.close()
      })
    },
    //点击编辑按钮
    btnedit(row) {
      //改变编辑状态
      row.isedit = true
      //当点击编辑 修改数据后 rowedit里面的数据发生修改  这时如果取消编辑 rowedit里面的数据啊还是修改后的数据
      //所有当点击编辑按钮后,重新修改为原始值
      row.rowedit.name = row.name,
        row.rowedit.description = row.description,
        row.rowedit.state = row.state
    },
    //行内编辑确定按钮
    async editok(row) {
      //判断修改的数据是否为空
      if (row.rowedit.name && row.rowedit.description) {
        const res = await updatarole({ ...row.rowedit, id: row.id })
        console.log(res);
        this.$message.success('更新成功')
        //这里不能调用获取角色信息的接口
        //如果调用获取角色信息接口 会将所有行的编辑状态设置成false 
        //所以更新页面数据需要重新赋值
        // 使用对象方法 object.assign
        //将修改后的rowedit数据添加到row里面
        Object.assign(row, {
          ...row.rowedit, isedit: false
        })
      }
      else {
        this.$message.warning('角色和描述不能为空')
      }
    },
    //删除按钮
    async delrole(id) {
      await delrole(id)
      this.$message.success('删除成功')
      //如果当前页中的数据只有一条,就将页码减一
      if (this.rolelist.length === 1) this.queryinfo.page--
      this.getroledata()
    },
    //分配权限按钮
    async setrolebtn(id) {
      this.activeid = id
      //每次点击分配权限都重新给树形组件的初始值赋值
      // 树形组件绑定的数据 是原始的权限数据
      this.perlist = JSON.parse(JSON.stringify(this.firstperlist))
      const res = await getbyidrole(id)
      this.byidroledata = res.permIds
      this.setroleshow = true
    },
    //关闭分配权限对话框
    perclose() {
      this.setroleshow = false
      //关闭对话框将书组件绑定的数组重新赋值为空
      this.perlist = []
      this.byidroledata = []
      this.activeid = null
    },
    //确认分配权限
    async queryperbtn() {
      //使用tree组件的实例上的方法获取以选中的keys数组
      const perid = this.$refs.treeper.getCheckedKeys()
      await putper({ id: this.activeid, permIds: perid })
      this.$message.success('添加权限成功')
      this.perclose()
    }
  },
  created() {
    this.getroledata()
  }
}
</script>
<style scoped>
.btnrole {
  margin: 5px 10px;
}
</style>